import { Component, h, render, VNode } from "vue"
import Notification from "./notification.vue"

/**
 * @param title 标题
 * @param message 通知栏正文内容
 * @param dangerouslyUseHTMLString 是否将 message 属性作为 HTML 片段处理
 * @param type 通知的类型
 * @param icon 自定义图标。 若设置了 type，则 icon 会被覆盖
 * @param customClass 自定义类名
 * @param duration 显示时间, 单位为毫秒。 值为 0 则不会自动关闭
 * @param position 自定义弹出位置
 * @param showClose 是否显示关闭按钮
 * @param onClose 关闭时的回调函数
 * @param onClick 点击 Notification 时的回调函数
 */
interface Option {
    title?: string,
    message?: string | VNode,
    dangerouslyUseHTMLString?: boolean,
    type?: 'success' | 'warning' | 'info' | 'error' | '',
    icon?: string | Component,
    customClass?: string,
    duration?: number,
    position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left',
    showClose?: boolean,
    onClose?: () => void,
    onClick?: () => void
}

class PeNotification {
    static zIndex = 8000

    static notification = (
        {
            title,
            message,
            dangerouslyUseHTMLString = false,
            type,
            icon,
            customClass,
            duration = 4500,
            position = 'top-right',
            showClose = true,
            onClose = () => { },
            onClick = () => { }
        }: Option
    ) => {
        const div = document.createElement("div")
        div.style.zIndex = `${++this.zIndex}`
        div.className = `pe-notification pe-notification-${position} ${customClass}`
        div.addEventListener('click', onClick)
        document.body.insertBefore(div, document.body.lastChild)
        this.getPosition(position)
        render(h(Notification, {
            title, message, dangerouslyUseHTMLString, type, icon, showClose,
            onClose: () => {
                onClose()
                this.removeDom(div, position, customClass)
            }
        }), div)
        if (duration > 0) {
            setTimeout(() => {
                this.removeDom(div, position, customClass)
            }, duration)
        }
    }

    // 获取定位
    static getPosition = (position: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left') => {
        const domList = document.querySelectorAll<HTMLDivElement>(`.pe-notification-${position}`)
        if (position.includes("top")) {
            let top = 20
            for (const dom of domList) {
                dom.style.top = `${top}px`
                top += dom.offsetHeight + 20
            }
        } else {
            let bottom = 20
            for (const dom of domList) {
                dom.style.bottom = `${bottom}px`
                bottom += dom.offsetHeight + 20
            }
        }
    }

    // 销毁消息元素
    static removeDom = (div: HTMLElement, position: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left', customClass?: string) => {
        // 销毁动画
        div.className = `pe-notification pe-notification-${position}-out ${customClass}`
        this.getPosition(position)
        setTimeout(() => {
            div.remove()
        }, 500)
    }
}

export default PeNotification